import { getImageAsync } from "./file";

export default class MaskCapture {
  constructor(canvas, option = {}) {
    const opt = {
      maskFillStyle: "rgba(0,0,0,0.3)",
      clipGraphAreaOnMask: true,
      maskImg: undefined,
      getGraphSize: undefined,
      getGraphPosition: undefined,
    };
    this.option = Object.assign(opt, option);
    this.canvas = canvas;
    this.ctx = canvas.getContext("2d");
    // console.log("option: ", this.option);
    this.init();
  }
  init() {
    this.getCanvasBcr();
    this.getGraphBcr();
    this.clearCanvas();
    this.drawMask();
    this.drawCaptureGraph().catch();
  }
  clearCanvas() {
    this.ctx.clearRect(0, 0, this.canvasBcr.w, this.canvasBcr.h);
  }
  getCanvasBcr() {
    this.canvasBcr = {
      w: this.canvas.clientWidth,
      h: this.canvas.clientHeight,
    };
  }
  getGraphBcr() {
    let getGraphSize = this.option.getGraphSize;
    let getGraphPosition = this.option.getGraphPosition;
    if (typeof getGraphSize !== "function") {
      getGraphSize = this.getGraphSize;
    }
    if (typeof getGraphPosition !== "function") {
      getGraphPosition = this.getGraphPosition;
    }
    const cW = this.canvasBcr.w;
    const cH = this.canvasBcr.h;
    const { width, height } = getGraphSize(cW, cH);
    const { left, top } = getGraphPosition(cW, cH, width, height);
    this.graphBcr = { w: width, h: height, x: left, y: top };
  }

  // eslint-disable-next-line no-unused-vars
  getGraphSize(cW, cH) {
    const width = cW * 0.777;
    const height = width / 0.625;
    return { width, height };
  }

  // eslint-disable-next-line no-unused-vars
  getGraphPosition(cW, cH, gW, gH) {
    const x = (cW - gW) / 2;
    const y = x * 1.2;
    return { left: x, top: y };
  }
  drawMask() {
    const { x, y, w, h } = this.graphBcr;
    const { w: cW, h: cH } = this.canvasBcr;
    const { maskFillStyle, clipGraphAreaOnMask } = this.option;
    this.ctx.save();
    this.ctx.fillStyle = maskFillStyle;
    this.ctx.fillRect(0, 0, cW, cH);
    if (clipGraphAreaOnMask) {
      this.ctx.clearRect(x, y, w, h);
    }
    this.ctx.restore();
  }
  drawMaskGraph(img) {
    const { x, y, w, h } = this.graphBcr;
    const nW = img.naturalWidth;
    const nH = img.naturalHeight;
    this.ctx.save();
    this.ctx.clearRect(x, y, w, h);
    this.ctx.drawImage(img, 0, 0, nW, nH, x, y, w, h);
    this.ctx.restore();
  }
  async drawCaptureGraph() {
    const { maskImg } = this.option;
    if (maskImg) {
      const img = await getImageAsync(maskImg);
      this.drawMaskGraph(img);
    }
  }
  capture(video, quality = 0.7) {
    const { width: vw, height: vh } = video;
    const { x, y, w, h } = this.graphBcr;
    let bcr = { x, y, w, h, vw, vh };
    bcr = Object.keys(bcr).reduce((res, key) => {
      return Object.assign(res, { [key]: bcr[key] * quality });
    }, {});
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    canvas.width = bcr.vw;
    canvas.height = bcr.vh;
    ctx.drawImage(video, 0, 0, bcr.vw, bcr.vh);
    const data = ctx.getImageData(bcr.x, bcr.y, bcr.w, bcr.h);
    ctx.clearRect(0, 0, bcr.vw, bcr.vh);
    canvas.width = data.width;
    canvas.height = data.height;
    ctx.putImageData(data, 0, 0);
    return canvas.toDataURL("image/png", 1);
  }
}
